package cn.actoncode.boot.framework.common.exception;

import cn.actoncode.boot.framework.common.exception.enums.DouyinMaErrorMsgEnum;
import cn.actoncode.boot.framework.common.exception.enums.KuaishouMaErrorMsgEnum;
import cn.actoncode.boot.framework.common.exception.enums.QqMaErrorMsgEnum;
import cn.actoncode.boot.framework.common.exception.enums.XfyunErrorMsgEnum;
import cn.actoncode.boot.framework.common.http.enums.PlatformType;
import cn.actoncode.boot.framework.common.json.PlatformJson;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 平台错误码.
 *
 * @author bin
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PlatformError {

    /**
     * 错误代码.
     */
    @JsonAlias({"err_no", "error", "code", "errcode", "err_code", "result", "errCode", "errno"})
    private int errorCode;

    /**
     * 错误信息.
     */
    @JsonAlias({"err_tips", "message", "errmsg", "err_msg", "error_msg", "desc", "errMsg"})
    private String errorMsg;

    /**
     * 本次会话的id
     * -- 讯飞
     */
    @JsonAlias({"sid", "request_id"})
    private String requestId;

    /**
     * 返回头
     * -- 讯飞
     */
    private Header header;

    /**
     * 返回数据体
     * -- 抖音:data, 讯飞:payload
     */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @JsonAlias({"data", "payload"})
    private ObjectNode data;

    /**
     * 返回json字符串
     */
    private String json;

    @Data
    class Header {
        private int code;
        private String message;
        private String sid;
    }

    public PlatformError(int errorCode, String errorMsg) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

    public static PlatformError parse(String json, PlatformType type) {
        final PlatformError platformError = PlatformJson.parse(json, PlatformError.class);
        switch (type) {
            case DOUYIN -> {
                final String msg = DouyinMaErrorMsgEnum.findMsgByCode(platformError.getErrorCode());
                if (msg != null) {
                    platformError.setErrorMsg(msg);
                }
            }
            case KUAISHOU -> {
                final String msg = KuaishouMaErrorMsgEnum.findMsgByCode(platformError.getErrorCode());
                if (msg != null) {
                    platformError.setErrorMsg(msg);
                }
            }
            case XFYUN -> {
                if (null != platformError.getHeader()) {
                    platformError.setErrorCode(platformError.getHeader().getCode());
                    platformError.setErrorMsg(platformError.getHeader().getMessage());
                    platformError.setRequestId(platformError.getHeader().getSid());
                }
                final String msg = XfyunErrorMsgEnum.findMsgByCode(platformError.getErrorCode());
                if (msg != null) {
                    platformError.setErrorMsg(msg);
                }
            }
            case QQ -> {
                final String msg = QqMaErrorMsgEnum.findMsgByCode(platformError.getErrorCode());
                if (msg != null) {
                    platformError.setErrorMsg(msg);
                }
            }
        }
        if (platformError.getErrorCode() == 0) {
            return platformError;
        }
        final String msg = XfyunErrorMsgEnum.findMsgByCode(platformError.getErrorCode());
        if (msg != null) {
            platformError.setErrorMsg(msg);
        }
        platformError.setJson(json);
        return platformError;
    }

    public <T> T getData(Class<T> t) {
        if (null == data && StrUtil.isEmpty(json)) {
            return null;
        } else if (null == data && StrUtil.isNotEmpty(json)) {
            return PlatformJson.parse(json, t);
        }
        return PlatformJson.convert(data, t);
    }

    @Override
    public String toString() {
        if (this.json == null) {
            return "错误代码：" + this.errorCode + ", 错误信息：" + this.errorMsg;
        }

        return "错误代码：" + this.errorCode + ", 错误信息：" + this.errorMsg + "，原始报文：" + this.json;
    }

}
